home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1998 June / SGI Freeware 1998 June.iso / dist / fw_ATxgopher.idb / usr / freeware / src / xgopher.1.3 / dirList.c.z / dirList.c
C/C++ Source or Header  |  1998-01-21  |  6KB  |  301 lines

  1. /* dirList.c
  2.    routines to manage the data structures for gopher directories */
  3.  
  4.      /*---------------------------------------------------------------*/
  5.      /* Xgopher        version 1.3     08 April 1993                  */
  6.      /*                version 1.2     20 November 1992               */
  7.      /*                version 1.1     20 April 1992                  */
  8.      /*                version 1.0     04 March 1992                  */
  9.      /* X window system client for the University of Minnesota        */
  10.      /*                                Internet Gopher System.        */
  11.      /* Allan Tuchman, University of Illinois at Urbana-Champaign     */
  12.      /*                Computing and Communications Services Office   */
  13.      /* Copyright 1992, 1993 by                                       */
  14.      /*           the Board of Trustees of the University of Illinois */
  15.      /* Permission is granted to freely copy and redistribute this    */
  16.      /* software with the copyright notice intact.                    */
  17.      /*---------------------------------------------------------------*/
  18.  
  19.  
  20.  
  21. #include <stdio.h>
  22.  
  23. #include "gopher.h"
  24. #include "dirList.h"
  25. #include "item.h"
  26. #include "listP.h"
  27.  
  28. #include "osdep.h"
  29.  
  30. static    gopherDirList    unusedDirs = {NULL, NULL};
  31.  
  32. static    int        firstDirAlloc  = TRUE;
  33.  
  34.  
  35. /* Directory list management routines:
  36.     acquireDir()            return ptr to a gopherDir structure
  37.     releaseDir(gopherDirP)        Return directory to the free list
  38.     previousDir(gopherDirP)        return a pointer to previous directory
  39.     nextDir(gopherDirP)        return a pointer to next directory
  40.     freeDirList(gopherDirP)        Free a list of directories
  41.     allocGopherDir(int)        Allocate n new gopher directories
  42.  
  43.    current directory list management:
  44.     getCurrentDir()            return a ptr to current directory
  45.     pushCurrentDir(gopherDirP)    Push a new directory to be current
  46.     popCurrentDir()            make previous directory current
  47.     getCurrentDirIndex()        return search string of curr directory
  48.     noCurrentDir()            T/F; does current directory exist
  49.     atFirstDir()            T/F; is current directory first one
  50.     checkDirStack()            freeing expired gopher items from stack
  51. */
  52.  
  53.  
  54. /* acquireDir 
  55.     Allocate a gopher directory from the free list */
  56.  
  57. gopherDirP
  58. acquireDir()
  59. {
  60.     gopherDirP    dir;
  61.  
  62.     if (unusedDirs.first == NULL) {
  63.         /* out of gopher directories, so allocate more */
  64.         allocGopherDir(firstDirAlloc ? dirStart : dirIncrement);
  65.         firstDirAlloc = FALSE;
  66.     }
  67.     dir = unusedDirs.first;
  68.     unusedDirs.first = dir->next;
  69.     if (unusedDirs.first == NULL) unusedDirs.last = NULL;
  70.  
  71.     dir->previous = dir->next = NULL;
  72.  
  73.     return dir;
  74. }
  75.  
  76.  
  77. /* releaseDir 
  78.     Return a gopher directory to the free list */
  79.  
  80. void
  81. releaseDir(dir)
  82. gopherDirP    dir;
  83. {
  84.     dir->next = unusedDirs.first;
  85.     unusedDirs.first = dir;
  86.     if (unusedDirs.last == NULL) unusedDirs.last = dir;
  87.  
  88.     return;
  89. }
  90.  
  91.  
  92. /* previousDir 
  93.     return a pointer to the directory previous to the given one */
  94.  
  95. gopherDirP
  96. previousDir(dir)
  97. gopherDirP    dir;
  98. {
  99.     if (dir == NULL) return NULL;
  100.     return dir->previous;
  101. }
  102.  
  103.  
  104. /* nextDir 
  105.     return a pointer to the directory following to the given one*/
  106.  
  107. gopherDirP
  108. nextDir(dir)
  109. gopherDirP    dir;
  110. {
  111.     if (dir == NULL) return NULL;
  112.     return dir->next;
  113. }
  114.  
  115.  
  116. /* freeDirList
  117.     Free a list of directories */
  118.  
  119. static void
  120. freeDirList(dir)
  121. gopherDirP    dir;
  122. {
  123.     gopherDirP    p;
  124.  
  125.     for (p=dir; p->next != NULL; p=p->next) ;
  126.  
  127.     if (unusedDirs.last == NULL) unusedDirs.last = p;
  128.     p->next = unusedDirs.first;
  129.     unusedDirs.first = dir;
  130.  
  131.     return;
  132. }
  133.  
  134.  
  135. /* allocGopherDir
  136.     Allocate n new gopher directories, adding them to the free list */
  137.  
  138. static void
  139. allocGopherDir(n)
  140. int    n;
  141. {
  142.     gopherDirP    dirList, p;
  143.     int        i;
  144.  
  145.     if (n <= 0) return;
  146.  
  147.     if ((dirList = (gopherDirP) malloc(n * sizeof(gopherDir))) == NULL) {
  148.         /* out of memory */
  149.         fprintf (stderr, "There is not enough memory to continue.\n");
  150.         exit(3);
  151.     }
  152.  
  153.     for (i=0, p=dirList; i<n-1; i++, p++) {
  154.         p->next = p+1;
  155.     }
  156.     p->next = NULL;
  157.     freeDirList(dirList);
  158.  
  159.     return;
  160. }
  161.  
  162. /* -----------------------------------------------------------------------
  163.    Special section for managing Current directory and the directory stack
  164.    ----------------------------------------------------------------------- */
  165.  
  166. static  gopherDirP      currentDir = NULL;    /* current directory pointer */
  167. static  gopherDirP      firstDir = NULL;    /* start of dir stack */
  168.  
  169.  
  170. /* getCurrentDir 
  171.     return a pointer to the current directory */
  172.  
  173. gopherDirP
  174. getCurrentDir()
  175. {
  176.     return currentDir;
  177. }
  178.  
  179.  
  180. /* pushCurrentDir
  181.     Push a new directory to the stack after the current one and
  182.     make the new one current. */
  183.  
  184. void
  185. pushCurrentDir(dir)
  186. gopherDirP    dir;
  187. {
  188.  
  189.     /* check for first directory in stack */
  190.  
  191.     if (currentDir == NULL) {
  192.         dir->previous = NULL;
  193.         firstDir = dir;
  194.     } else {
  195.  
  196.         /* discard "popped" directories, if any */
  197.  
  198.         reallyPopFrom(currentDir->next);
  199.  
  200.         dir->previous = currentDir;
  201.         currentDir->next = dir;
  202.     }
  203.  
  204.     dir->next = NULL;
  205.     currentDir = dir;
  206.  
  207.     return;
  208. }
  209.  
  210.  
  211. /* popCurrentDir
  212.     Just move back to previous directory.  Don't actually
  213.     delete the subsequent ones until a new push is done. */
  214.  
  215. void
  216. popCurrentDir()
  217. {
  218.     if (currentDir == NULL) return;
  219.     if (currentDir->previous == NULL) return;
  220.  
  221.     currentDir = currentDir->previous;
  222.  
  223.     return;
  224. }
  225.  
  226.  
  227. /* reallyPopFrom
  228.    discard and reclaim the directories in the stack starting from
  229.    the given one */
  230.    
  231. static void
  232. reallyPopFrom(d)
  233. gopherDirP    d;
  234. {
  235.     gopherDirP    tmp;
  236.  
  237.     while (d != NULL){
  238.         tmp = d->next;
  239.         freeDir(d);
  240.         d = tmp;
  241.     }
  242. }
  243.  
  244.  
  245. /* getCurrentDirIndex 
  246.     return a pointer to the index search string of the current directory */
  247.  
  248. char *
  249. getCurrentDirIndex()
  250. {
  251.     return getItemIndex(currentDir->selectorItem);
  252. }
  253.  
  254.  
  255. /* atFirstDir 
  256.     return TRUE is current directory is the first one, FALSE otherwise */
  257.  
  258. BOOLEAN
  259. atFirstDir()
  260. {
  261.     return ((currentDir == NULL) || (currentDir->previous == NULL));
  262. }
  263.  
  264.  
  265. /* noCurrentDir 
  266.     return TRUE is there is no current directory, yet; FALSE otherwise */
  267.  
  268. BOOLEAN
  269. noCurrentDir()
  270. {
  271.     return (currentDir == NULL);
  272. }
  273.  
  274.  
  275. /* clearDirStack
  276.    wipe out the cirectory stack; set it back to its initial state */
  277.  
  278. void
  279. clearDirStack()
  280. {
  281.     reallyPopFrom(firstDir);
  282.     currentDir = NULL;
  283.     firstDir = NULL;
  284. }
  285.  
  286.  
  287. /* checkDirStack
  288.     traverse directory stack freeing expired gopher items */
  289.  
  290. void
  291. checkDirStack()
  292. {
  293.     gopherDirP    d;
  294.  
  295.     for (d=firstDir; d != NULL; d = d->next) {
  296.         if (d->created != NOT_LOADED) clearDirWhenOld(d);
  297.     }
  298.  
  299.     return;
  300. }
  301.